// import Client from '@alicloud/bailian20230601';
import Client from '@alicloud/bailian20230601';
import https from 'https';
import { v4 as uuidv4 } from 'uuid';
import { prisma } from '../service/mysql.js';

const bailianClient = new Client.default({
    accessKeyId: process.env.BAILIAN_AK,
    accessKeySecret: process.env.BAILIAN_SK,
    endpoint: process.env.BAILIAN_ENDPOINT
});

// 获取百练平台token
export const createBailianToken = async function () {
    try {
        const response = await bailianClient.createToken(
            { agentKey: process.env.BAILIAN_AGENT_KEY }
        );

        const responseBody = response.body
        if (responseBody === null) {
            throw new Error('failed to create token')
        }

        if (responseBody.success !== true) {
            let requestId = responseBody.requestId;
            if (requestId == null) {
                requestId = response.headers["x-acs-request-id"];
            }

            let error = "failed to create token " + responseBody.message + ", requestId: " + requestId;
            throw new Error(error)
        }

        const data = responseBody.data
        if (data === null) {
            throw new Error("failed to create token");
        }
        return data.token;
    } catch (err) {
        console.error('failed to create token, err: ', err);
    }
}

// 百练应用交互
export const requestBailian = async function (appId, prompt, bizParams, context) {
    // 获取token
    const token = await createBailianToken();
    const postData = JSON.stringify({
        "RequestId": uuidv4(), // 替换为你的实际 RequestId
        "AppId": appId, // 替换为你的实际 AppId
        "Prompt": prompt,
        "HasThoughts": true,
        "BizParams": bizParams,
        "Parameter": {
            "TopK": 1,
            "Temperature": 0.01
        }
    });

    const options = {
        hostname: 'bailian.aliyuncs.com',
        port: 443,
        path: '/v2/app/completions',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Authorization': `Bearer ${token}`,
            'Accept-charset': 'utf-8',
            'Content-Length': Buffer.byteLength(postData)
        }
    };

    let responseBody = '';
    let resData = {
        output: {
            text: '',
            incrementalText: '',
            finish_reason: null
        },
        usage: {
            total_tokens: 0,
            input_tokens: 0,
            output_tokens: 0,
        },
        err: '',
        request_id: null
    };
    try {
        const req = https.request(options, (res) => {
            res.setEncoding('utf8');

            res.on('data', (chunk) => {
                responseBody += chunk;
            });
        });

        req.on('error', (e) => {
            throw e;
        });

        req.write(postData);
        req.end();

        // 等待请求结束
        await new Promise((resolve, reject) => {
            req.on('close', resolve);
            req.on('error', reject);
        });

        const responseObj = JSON.parse(responseBody);
        resData.request_id = responseObj.RequestId;
        
        if (!responseObj.Success) {
            console.error('bailian process error prompt = ', prompt);
            throw new Error(responseObj.Message);
        }

        resData = {
            output: {
                incrementalText: null,
                text: responseObj.Data.Text,
                finish_reason: null
            },
            usage: { 
                total_tokens: responseObj.Data.Usage[0].InputTokens + responseObj.Data.Usage[0].OutputTokens, 
                input_tokens: responseObj.Data.Usage[0].InputTokens, 
                output_tokens: responseObj.Data.Usage[0].OutputTokens 
            },
            request_id: responseObj.RequestId
        }
        
        if (resData.output.text === 'REJECT') {
            throw new Error('无法回答该问题');
        }

        await prisma.t_llm_log.create({
            data: {
                input_tokens: resData.usage.input_tokens,
                output_tokens: resData.usage.output_tokens,
                total_tokens: resData.usage.total_tokens,
                prompt: prompt,
                content: resData.output.text,
                response: JSON.stringify(resData),
                status: 'success',
                request_id: resData.request_id,
                chat_request_id: context.requestId
            }
        });
        return resData;
    } catch (error) {
        console.error(error);
        resData.err = error.message;
        await prisma.t_llm_log.create({
            data: {
                input_tokens: resData.usage.input_tokens,
                output_tokens: resData.usage.output_tokens,
                total_tokens: resData.usage.total_tokens,
                prompt: prompt,
                content: resData.output.text,
                response: JSON.stringify(resData),
                status: 'failed',
                error: error.message,
                request_id: resData.request_id,
                chat_request_id: context.requestId
            }
        });
        throw new Error(`n2data 请求失败: ${error}`);
    }
}